home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-02
/
gametp20.zip
/
VGAKERN.INT
< prev
next >
Wrap
Text File
|
1992-11-06
|
26KB
|
762 lines
Unit VgaKern;
{ VgaKern version 3.6 Copyright (C) 1992 Scott D. Ramsay }
{ ramsays@access.digex.com }
{ This unit is specifically for Mode 13h (320x200x256). It is a }
{ lot faster than using the BGI drivers (VGA256.BGI). Majority of }
{ the code is written using BASM. This will work on 286 machines or }
{ higher. "I don't know about the P5 chip though." ;) }
{ This is the raw unit of the lib. Most of the basic low level }
{ routines are here. }
{ VGAKERN.TPU can be used freely in commerical and non-commerical }
{ programs. As long as you don't give yourself credit for writing }
{ this portion of the code. When distributing it (free only), please }
{ include all files and samples so others may enjoy using the code. }
{ Enjoy. }
{ Please bear with my comments. I'm not a tech-writer. You're more }
{ than welcome to modify the comments in this file for people to }
{ understand. "Except for my name." :) }
{ Changes from 3.4: }
{ New procedure: ColorsChange(var color:rgblist;filter:rgbtype);}
{ Changes a palette based on the filter }
Interface
const
VidSet : boolean = true; { When set to FALSE, OPENMODE() does }
{ clear the vga screen to black }
{ e.g. ah=$93 instead of ah=$13 }
{ See dos ref. for the set of HI-bit }
MaxPages = 8; { Maxium virtual pages allowed }
WinMinX : word = 0; { WinMin% sets the boundry for CLINE }
WinMinY : word = 0; { This is the only function that }
WinMaxX : word = 319; { does any clipping. (Clipping slows }
WinMaxY : word = 199; { slows functions) }
type
{ RGBType/RGBlist handles the color palette }
RGBType = record
red,green,blue : byte;
end;
RGBlist = array[0..255] of RGBType;
{ Same as then record declared in TVISION's OBJECTS unit }
PtrRec = record
ofs,seg : word;
end;
var
PrevMode, { previous }
crpg : byte; { current active page }
scnseg,scnofs : word; { current page address }
pages : array[1..MaxPages] of pointer; { page pointers }
thdmat : set of byte; { set for mattevsp }
vspcnt, { vsp last load count }
maxpage : word; { pages used }
zdc : RGBlist; { all black palette }
{ See Implementation section for description of functions }
procedure ColorsChange(var color:rgblist;filter:rgbtype);
function LoadVSP(fn:string;var buff):integer;
procedure MatteVsp(var from,too);
procedure VSinc;
procedure SetDefaultColors;
procedure Switch(var a,b:integer);
procedure Parse(var x,y:integer);
function BuffSize(width,height:integer):word;
function ImageSize(var image):word;
procedure ImageDims(var image;var width,height:integer);
procedure SetPtr(var i:PtrRec;var buff);
function pt(x,y:integer):word;
procedure OpenMode(npages:byte);
function Point(x,y:integer;pg:byte):byte;
procedure Pset(x,y:integer;n:byte);
procedure fPcopy(var from,too);
procedure Pcopy(from,too:byte);
procedure FastMatte(x1,y1,x2,y2:integer;var from,too);
procedure SwapMatte(x1,y1,x2,y2:integer;from,too:byte);
procedure Matte(x1,y1,x2,y2:integer;from,too:byte);
procedure Line(x1,y1,x2,y2:integer;n:byte);
procedure Bar(x1,y1,x2,y2:integer;n:byte);
procedure Rectangle(x1,y1,x2,y2:integer;n:byte);
procedure Circle(x1,y1,r:integer;n:byte);
procedure Ellipse(xc,yc,a0,b0:integer;c:byte);
procedure fBitDraw(x,y:word;var buff);
procedure Cls(n:byte);
procedure CloseMode;
procedure FastGet(x1,y1,x2,y2:integer;var image);
procedure GetPic(x1,y1,x2,y2:integer;var image);
procedure FastPut(x1,y1:integer;var image);
procedure PutPic(x1,y1:integer;var image;rmw:byte);
procedure SetPageActive(page:byte);
procedure GetColor(num:byte;var red,green,blue:byte);
procedure SetColor(num,red,green,blue:byte);
procedure fSetColors(var colors);
procedure fGetColors(var colors);
procedure FadeIn(steps:word;var color1,color2);
procedure FadeOut(steps:word;var color1,color2);
function LoadColors(filename:string;var colors;count:integer):integer;
function SaveColors(filename:string;var colors;count:integer):integer;
procedure Paint(x,y:integer;n:byte);
procedure CopyTo(x1,y1,x2,y2,x,y:integer;from,too:byte);
procedure BitDraw(x,y:integer;var image,matte);
procedure BitErase(x,y:integer;page:byte;var matte);
procedure DispLayer(x,y:integer;var pic,mat,virt;plv:byte);
procedure EraseLayer(x,y:integer;bkpage:byte;var mat,virt;plv:byte);
procedure DispVirt(x,y:integer;var mat,virt;plv:byte);
procedure EraseVirt(x,y:integer;var mat,virt;plv:byte);
procedure CopyVirt(x,y:integer;var mat,v1,v2;plv:byte);
procedure DispSprite(x,y:integer;var pic,mat,virt;plv:byte);
procedure EraseSprite(x,y:integer;var mat,v2;bkpage,plv:byte);
function AnalyzeScreen:byte;
procedure MemWrite(var source,dest;size:word;var off:longint);
procedure MemRead(var source,dest;size:word;var off:longint);
procedure FastWPut(x1,y1:integer;var image);
procedure FastWMatte(x1,y1,x2,y2:integer;var from,too);
Implementation
(***********************************************************************)
function LoadVSP(fn:string;var buff):integer;
Loads a VSP (Vga SPrite) file. The procedure automatically
allocates memory for the images onto the heap space
fn:string The VSP file name
buff The location to place the sprites
NOTE: buff must be of type POINTER
or an array of pointers
e.g.
var
sprite_1 : pointer;
sprite_2 : array[1..sprites_in_file] of pointer;
The format of a sprite file:
{ BYTE SIZE DESCRIPTION
0..1 word width of sprite
2..3 word height of sprite
4..(width*height+4) byte pixel information
n word width of next sprite
n+2 word height of next sprite
.
.
.
}
example:
const
sprites_in_file = 10;
var
list_sprite : array[1..sprites_in_file] of pointer;
a_sprite : pointer;
begin
loadvsp('sprite01.vsp',list_sprite);
loadvsp('sprite02.vsp',a_sprite);
fastput(10,10,list_sprite[2]^);
fastput(100,100,a_sprite^);
end;
(***********************************************************************)
procedure MatteVsp(var from,too);
Creates a VSP matte, the matte is used for identifying
transparent color in sprites using the set THDMAT for
the transparent colors. The "too" sprite memory must
be allocated or a static array large enough to fit the
entire sprite.
e.g
var
sprite1 : pointer; { <- need to allocate }
sprite2 : array[1..260] of byte; { <- ready to use }
getmem(sprite,BuffSize(16,16)); { allocate mem for 16x16 sprite }
example:
const
sprite_size = 1000;
var
sprite,sprite_matte : pointer;
sprites : array[0..1] of pointer;
mattesprite : array[1..sprite_size] of byte;
begin
.
.
.
THDMAT := [0,4,5]; { Transparent colors for mattevsp are now 0,4,5 }
MatteVsp(sprite^,sprite_matte^);
MatteVsp(sprite[0]^,sprite[1]^);
THDMAT := [0]; { 0 is the only transparent color }
MatteVsp(sprite[0]^,mattesprite);
}
(***********************************************************************)
procedure VSinc;
Waits for VBI "Vertical Blanking Interval"
(***********************************************************************)
procedure SetDefaultColors;
Sets to the default palette. Colors 0..15 are the default EGA colors
where 16..255 are different intensities of those colors
(***********************************************************************)
procedure Switch(var a,b:integer);
Switches the values of A and B. Quickly!
a := a xor b;
b := a xor b;
a := a xor b; { do the math, it works! }
(***********************************************************************)
procedure Parse(var x,y:integer);
Clips the values of X and Y to be in the range 0..319, 0..199
if x<0 then x := 0
else
if x>319
then x := 319;
if y<0 then y := 0
else
if y>199
then y := 199;
(***********************************************************************)
function BuffSize(width,height:integer):word;
Returns the bytes required to store a sprite of size
width, height.
(***********************************************************************)
function ImageSize(var image):word;
Returns the amount of memory the sprite uses. (in bytes)
(***********************************************************************)
procedure ImageDims(var image;var width,height:integer);
Returns the width and height of a sprite
(***********************************************************************)
procedure SetPtr(var i:PtrRec;var buff);
Sets the Segment and offset of buff to the i:PTRREC
(***********************************************************************)
function pt(x,y:integer):word;
Calcuates the screen offset of x,y.
example:
const
x = 160;
y = 100;
.
.
.
begin
mem[$A000:pt(x,y)] := 1; { Places a pixel of color 1 at (x,y) }
end;
(***********************************************************************)
procedure OpenMode(npages:byte);
Sets to mode 13h, Initalizes variables, Allocates virtual pages,
and sets default palette. (The first call you should do before
using the other functions.
npages:byte; { The number of pages to allocate }
example:
openmode(3); { allocates 2 virtual pages to the heap }
{ page 1 is always $A000:0 }
You must copy pages 2..n to page 1 to view. The visual
page is always page 1.
(***********************************************************************)
function Point(x,y:integer;pg:byte):byte;
Returns the pixel value at (X,Y) on page (PG)
(***********************************************************************)
procedure Pset(x,y:integer;n:byte);
Sets a pixel value on the current page of (N) at (X,Y)
(***********************************************************************)
procedure fPcopy(var from,too);
Copies a page to another page, Fast.
example:
fPcopy(pages[1]^,pages[2]^); { copies the contents of page 1 to page 2 }
The untyped parameters allows for user created virtual pages. Such
at EMS memory. e.g. fPcopy(pages[2]^,mem[EMSsegment,0]);
(***********************************************************************)
procedure Pcopy(from,too:byte);
Copies a page to another page.
Pcopy(2,4); { Copies the contents of page 1 to page 4 }
(***********************************************************************)
procedure FastMatte(x1,y1,x2,y2:integer;var from,too);
Copies a rectanglar region (x1,y1,x2,y2) at FROM to TOO.
example:
FastMatte(10,10,100,100,pages[1]^,pages[2]^);
(***********************************************************************)
procedure SwapMatte(x1,y1,x2,y2:integer;page1,page2:byte);
Switches a rectanglar region (x1,y1,x2,y2). Not blinding fast.
example:
SwapMatte(0,0,319,199,4,2); { exchanges contents of page 4, page 2
(***********************************************************************)
procedure Matte(x1,y1,x2,y2:integer;from,too:byte);
Same a FastMatte. Slower.
example:
Matte(100,100,120,145,1,2);
(***********************************************************************)
procedure Line(x1,y1,x2,y2:integer;n:byte);
Draws a line on the current page. Alot faster than BGI drivers.
(***********************************************************************)
procedure Bar(x1,y1,x2,y2:integer;n:byte);
Draws a filled rectangle on the current page
(***********************************************************************)
procedure Rectangle(x1,y1,x2,y2:integer;n:byte);
Draws a rectangle on the current page
(***********************************************************************)
procedure Circle(x1,y1,r:integer;n:byte);
Draws a circle with a radius of R and color N on the current page
(***********************************************************************)
procedure Ellipse(xc,yc,a0,b0:integer;c:byte);
Draws an ellipse with horiz radius of a0 and vertical radius of b0
(***********************************************************************)
procedure fBitDraw(x,y:word;var buff);
Draws a sprite on the current page with color 0 being transparent. Fast.
(***********************************************************************)
procedure Cls(n:byte);
Clear the current page to color (N)
(***********************************************************************)
procedure CloseMode;
Deallocates virtual pages and restores the display mode.
(***********************************************************************)
procedure FastGet(x1,y1,x2,y2:integer;var image);
Gets a sprite from the current page at the region (x1,y1,x2,y2) faster
than GetPic.
example:
var
sprite : pointer;
.
.
.
FastGet(10,10,24,26,sprite^);
(***********************************************************************)
procedure GetPic(x1,y1,x2,y2:integer;var image);
Same as FastGet.
(***********************************************************************)
procedure FastPut(x1,y1:integer;var image);
Puts a sprite onto the current page. Fast. With no transparency.
example:
var
sprite : array[0..100] of byte;
listsprite : array[0..2] of pointer;
.
.
.
FastPut(10,10,sprite);
FastPut(20,20,listsprite[2]^);
(***********************************************************************)
procedure PutPic(x1,y1:integer;var image;rmw:byte);
Puts a sprite onto the current page.
values of RMW
0 = MOV
1 = XOR
2 = OR
3 = AND
4 = NOT
The above values are the same as XORput,NormPut ... defined in
the unit GRAPH.TPU
(***********************************************************************)
procedure SetPageActive(page:byte);
Changes the active page specified by (PAGE). Updates the values
of SCNSEG, SCNOFS.
example:
SetPageActive(1); { SCNSEG = $A000, SCNOFS = 0 }
User defined pages can be set by modifing SCNSEG and SCNOFS directly.
e.g.
var
ascreen : pointer;
.
.
.
getmem(ascreen,64000); { screen size = 64000 bytes }
SCNSEG := seg(ascreen^);
SCNOFS := ofs(ascreen^);
line(0,0,319,199,4); { draws a line on ascreen }
(***********************************************************************)
procedure GetColor(num:byte;var red,green,blue:byte);
Returns the red, green, blue values of color (num)
(***********************************************************************)
procedure SetColor(num,red,green,blue:byte);
Sets the red, green, blue values of color (num)
(***********************************************************************)
procedure fSetColors(var colors);
Sets the entire palette. (With out flicker)
colors is usually variable of type RGBlist
(***********************************************************************)
procedure fGetColors(var colors);
Gets the current color palette.
(***********************************************************************)
procedure FadeIn(steps:word;var color1,color2);
Fades in the current palette from color1 to color2 in (STEPS) steps.
example:
var
MyPalette : RGBlist;
.
.
.
LoadColors('colors.pal',MyPalette,256);
FSetColors(zdc); { black out the palette. ZDC defined in unit }
FadeIn(70,zdc,MyPalette);
(***********************************************************************)
procedure FadeOut(steps:word;var color1,color2);
Fades out the current palette from color2 to color1 in (STEPS) steps.
example:
var
MyPalette : RGBlist;
.
.
.
LoadColors('colors.pal',MyPalette,256);
FSetColors(MyPalette);
.
.
.
FadeOut(70,zdc,MyPalette); { Fades the screen to black }
(***********************************************************************)
function LoadColors(filename:string;var colors;count:integer):integer;
Loads a list of RGBtypes.
filename:string The palette file.
colors Location to store the palette
count Number of colors to read
example:
LoadColors('colors.pal',MyPalette,256);
FSetColors(MyPalette);
(***********************************************************************)
function SaveColors(filename:string;var colors;count:integer):integer;
Saves a list of RGBtypes.
filename:string The palette file.
colors palette to save
count Number of colors to save
example:
SaveColor('black.pal',zdc,256);
(***********************************************************************)
procedure Paint(x,y:integer;n:byte);
Does a flood fill at (x,y) with color n. Changes only
the surrounding region at the color (x,y). Slow, my own
coding, but it works.
(***********************************************************************)
procedure CopyTo(x1,y1,x2,y2,x,y:integer;from,too:byte);
Copies a rectangular region (x1,y1,x2,y2) to (x,y) (top,left corner)
from,too indicates page number.
Does check for overlapping regions if FROM and TOO are the same page.
(I hate checking code. Slows things down. Write the program to
avoid overlapping. "Just my 2cents" sorry.)
(***********************************************************************)
procedure BitDraw(x,y:integer;var image,matte);
Puts a sprite, on the screen transparent areas are specified
by the matte sprite. Usefull for images that change transparency.
(The imgage doesn't change, only the matte);
The how BitDraw works:
Checks the each pixel in "matte". If the pixel value in
matte is non-zero, then the corresponding pixel in "image"
is drawn onto the current page.
NOTE: the image and matte sprites should be the same size.
See also: MatteVsp, DispLayer
(***********************************************************************)
procedure BitErase(x,y:integer;page:byte;var matte);
Erases the region on the current page by the region on (page) at X,Y.
example:
SetActivePage(1);
BitDraw(x,y,ball_sprite^,ball_matte^);
BitErase(x,y,2,ball_matte^);
{ page 2 can be the background, BitErase erases only the
areas affected by the BitDraw }
(***********************************************************************)
procedure DispLayer(x,y:integer;var pic,mat,virt;plv:byte);
Displays a Sprite (pic) and its matte (mat) on the current page.
Based on the sprites level. (plv) is the sprite layer number. (virt)
virtual page which keeps track of "DispLayer" sprites on screen.
Think of the display having 256 layers. Layer 0 is furthest back and
layer 255 is the top layer. For example, a sprite "Displayer" with
plv=4 will only overwrite sprites that have been written with a plv
value less than 4. Sprites greater than 4 will be unaffected.
The how DispLayer works:
Functions the same as BitDraw, except that it also checks the
screen location on the "virt" page. If that pixel value is less
than the "plv" value, then the pixel is drawn.
Use the "DispLayer" function with DispVirt to update the virtual page.
See sample programs for use of this. (I can't explain it very well, huh)
example:
DispLayer(x,y,sprite^,sprite_matte^,pages[2]^,4);
{ Draws the sprite at layer 4 }
DispVirt(x,y,sprite_matte^,pages[2]^,plv);
{ Updates the virtual page }
See Also:
BitDraw, BitErase, EraseLayer
(***********************************************************************)
procedure EraseLayer(x,y:integer;bkpage:byte;var mat,virt;plv:byte);
Erases a Sprite on the current page.
x,y : coordinates to place the sprite
bkpage : the background page to write to the current screen.
mat : the sprite matte
plv : sprite value
Functionally the same as BitErase. Except that the pixel value
at (virt) must less than equal to (plv)
(***********************************************************************)
procedure DispVirt(x,y:integer;var mat,virt;plv:byte);
Updates the (virt) "virtual" page.
See EraseLayer, BitDraw, BitErase, DispLayer
(***********************************************************************)
procedure EraseVirt(x,y:integer;var mat,virt;plv:byte);
Erases the (virt) "virtual" page.
See EraseLayer, BitDraw, BitErase, DispLayer
(***********************************************************************)
procedure CopyVirt(x,y:integer;var mat,v1,v2;plv:byte);
Copies the (plv) on page (v1) to (v2).
Example:
CopyVirt(x,y,sprite_mat^,pages[2]^,pages[3]^,4);
(***********************************************************************)
procedure DispSprite(x,y:integer;var pic,mat,virt;plv:byte);
Calls DispLayer(x,y,pic,mat,virt,plv); and
Calls DispVirt(x,y,mat,virt,plv);
(***********************************************************************)
procedure EraseSprite(x,y:integer;var mat,v2;bkpage,plv:byte);
Calls EraseVirt(x,y,mat,virt,plv); and
Calls EraseLayer(x,y,bkpage,mat,virt,plv);
(***********************************************************************)
function AnalyzeScreen:byte;
Returns the color number that is most used on the screen.
Used by SavePTR in unit IMAGING.TPU
(***********************************************************************)
procedure MemWrite(var source,dest;size:word;var off:longint);
Copies a block of memory from "source" to "dest" of size "size".
off: is the starting offset of "dest". and
returns (off+size). The next byte(s) to be read.
(***********************************************************************)
procedure MemRead(var source,dest;size:word;var off:longint);
Same as MemWrite. Except "off" specifies the starting
offset of "source"
(***********************************************************************)
procedure FastWPut(x1,y1:integer;var image);
Same as FastPut. But moves WORDS, instead of BYTES.
note: Make sure the width of the sprite is an even value.
(***********************************************************************)
procedure FastWMatte(x1,y1,x2,y2:integer;var from,too);
Same as FastMatte. But moves WORDS instead of BYTES.
note: Make sure that (x2-x1)+1 is an even value.
(***********************************************************************)
procedure ColorsChange(var color:rgblist;filter:rgbtype);
Changes a palette based on the filter
For example: To change a palette to gray scale.
const
GrayColor : RGBtype =
(red:63;green:63;blue:63);
var
MyColors,
MyPalette : RGBlist;
DYellow : RGBtype;
.
.
.
fsetcolor(MyPalette); { My Color palette }
ColorsChange(MyPalette,GrayColor);
fsetcolor(MyPalette); { My color palette is now gray scale }
To make a dark yellow color filter:
DYellow.red := 43;
DYellow.green := 30;
DYellow.blue := 4;
ColorsChange(MyColors,DYellow);
(***********************************************************************)
As you will notice. Some functions are similar. Such as:
PUTPIC, FASTPUT, FASTWPUT
MATTE, FASTMATTE, FASTWMATTE
This unit is a result of alot of revisions. Notice it is version 3.5b
eventhough this is it first public release.
I just kept the older versions of the functions in for my own
compatiblity. "Lucky for Turbo's Smart Linking. ;)"
If you have any problems, e-mail at:
ramsays@access.digex.com
The TPU units can be used freely with in your programs. If you want
the source code, more samples or swap-talk, just e-mail me. I'll give
sample use-code for free. Actual TPU-source code prices can be discussed.
Scott D. Ramsay